﻿using System;
using System.Linq.Expressions;
using NHibernate.Expression.Extensions.Utils;

namespace NHibernate.Expression.Extensions {
    public static class ProjectionsEx {
        public static AggregateProjection Avg<T>(Expression<Func<T, object>> property) {
            return Projections.Avg(property.MemberName());
        }

        public static CountProjection Count<T>(Expression<Func<T, object>> property) {
            return Projections.Count(property.MemberName());
        }

        public static CountProjection CountDistinct<T>(Expression<Func<T, object>> property) {
            return Projections.CountDistinct(property.MemberName());
        }

        public static PropertyProjection GroupProperty<T>(Expression<Func<T, object>> property) {
            return Projections.GroupProperty(property.MemberName());
        }

        public static AggregateProjection Max<T>(Expression<Func<T, object>> property) {
            return Projections.Max(property.MemberName());
        }

        public static AggregateProjection Min<T>(Expression<Func<T, object>> property) {
            return Projections.Min(property.MemberName());
        }

        public static AggregateProjection Sum<T>(Expression<Func<T, object>> property) {
            return Projections.Sum(property.MemberName());
        }

        public static PropertyProjection Property<T>(Expression<Func<T, object>> property) {
            return Projections.Property(property.MemberName());
        }

        private static string Prefix(string p, string m) {
            return string.Format("{0}.{1}", p, m);
        }

        private static string Prefix<T>(string p, Expression<Func<T, object>> m) {
            return Prefix(p, m.MemberName());
        }

        public static AggregateProjection Avg<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.Avg(Prefix(prefix, property));
        }

        public static CountProjection Count<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.Count(Prefix(prefix, property));
        }

        public static CountProjection CountDistinct<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.CountDistinct(Prefix(prefix, property));
        }

        public static PropertyProjection GroupProperty<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.GroupProperty(Prefix(prefix, property));
        }

        public static AggregateProjection Max<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.Max(Prefix(prefix, property));
        }

        public static AggregateProjection Min<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.Min(Prefix(prefix, property));
        }

        public static AggregateProjection Sum<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.Sum(Prefix(prefix, property));
        }

        public static PropertyProjection Property<T>(string prefix, Expression<Func<T, object>> property) {
            return Projections.Property(Prefix(prefix, property));
        }
    }
}